import { Injectable }  from '@angular/core';
import { Response }    from '@angular/http';
import { Router }      from '@angular/router';
import { Observable }  from 'rxjs/Observable';
import { Store }       from '@ngrx/store';
import { environment } from '../../../environments/environment';
import { HttpService } from './http.service';
import { AppState }    from '../../interfaces';
import { AuthActions } from '../../auth/actions/auth.actions';

// custom import router

@Injectable()
export class AuthService {

  /**
   * Creates an instance of AuthService.
   * @param {HttpService} http
   * @param {AuthActions} actions
   * @param {Store<AppState>} store
   *
   * @memberof AuthService
   */
  constructor(
    private http:    HttpService,
    private actions: AuthActions,
    private store:   Store<AppState>,
    private router:  Router
  ) {

  }

  /**
   *
   *
   * @param {any} data
   * @returns {Observable<any>}
   *
   * @memberof AuthService
   */

  login(data): Observable<any> {
    // let retData: any;
    // const ret = this.http.post('sign_in', { spree_user: data });
    // ret.map( (res: Response) => {
    //        retData = res.json();
    //        if ( !retData.error) {
    //          this.setTokenInLocalStorage( retData);
    //          this.store.dispatch( this.actions.loginSuccess());
    //        } else {
    //          this.http.loading.next( {
    //            loading: false,
    //            hasError: true,
    //            hasMsg: 'Please enter valid Credentials'
    //          });
    //        }
    //      });
    // console.log(data);
    //
    // return data;

    return this.http.post(
      '/sign_in/',
      data
    ).map((res: Response) => {
      // data = this.extractData;
      console.log('------ http post method ------');
      // data = res.json();
      console.log('login function data: ---', data);
      if (!data.error) {
        // Setting token after login
        console.log('--- data login function ---', res);
        this.setTokenInLocalStorage(res);
        console.log('set token in local storage : ---', this.setTokenInLocalStorage(data));
        this.store.dispatch(this.actions.loginSuccess());
      } else {
        this.http.loading.next({
          loading: false,
          hasError: true,
          hasMsg: 'Please enter valid Credentials'
        });
      }
      console.log('return data: ---', data);
      return data;
    });
    // catch should be handled here with the http observable
    // so that only the inner obs dies and not the effect Observable
    // otherwise no further login requests will be fired
    // MORE INFO https://youtu.be/3LKMwkuK0ZE?t=24m29s
  }

  /**
   *
   *
   * @param {any} data
   * @returns {Observable<any>}
   *
   * @memberof AuthService
   */
   // {user_token: data}
  register(data): Observable<any> {
    return this.http.post(
      '/sign_up/',
      data
    ).map((res: Response) => {
      // data = this.extractData;
      data = res.json();
      console.log('sign up data in register ---', data);
      if (!data.errors) {
        // Setting token after login
        // console.log('registe form data ---', data);
        // this.setTokenInLocalStorage(res.json());
        console.log('register service......');
        this.store.dispatch(this.actions.signupSuccess());
        console.log('after...');
      } else {
        this.http.loading.next({
          loading: false,
          hasError: true,
          hasMsg: 'Please enter valid Credentials'
        });
      }
      // return this.extractData;
      return res.json();
    });
    // catch should be handled here with the http observable
    // so that only the inner obs dies and not the effect Observable
    // otherwise no further login requests will be fired
    // MORE INFO https://youtu.be/3LKMwkuK0ZE?t=24m29s
  }

  /**
   *
   *
   * @returns {Observable<any>}
   *
   * @memberof AuthService
   */
  authorized(): Observable<any> {
    console.log('authenticated......');
    return this.http
      .get('/verify_token/')
      .map((res: Response) => res.json());
      // .map((res: Response) => this.extractData)
    // catch should be handled here with the http observable
    // so that only the inner obs dies and not the effect Observable
    // otherwise no further login requests will be fired
    // MORE INFO https://youtu.be/3LKMwkuK0ZE?t=24m29s
  }

  /**
   *
   *
   * @returns
   *
   * @memberof AuthService
   */
  logout() {
    return this.http.get('/logout/')
      .map((res: Response) => {
        // Setting token after login
        // localStorage.removeItem('user');
        this.store.dispatch(this.actions.logoutSuccess());
        localStorage.removeItem('user');
       // console.log(localStorage.removeItem('user'));
        // this.router.navigateByUrl('/auth/login');
        this.router.navigate(['/auth/login']);
        return res.json();
      });
  }

  /**
   *
   *
   * @private
   * @param {any} user_data
   *
   * @memberof AuthService
   */
  private setTokenInLocalStorage(user_data): void {
    console.log('user data : ---' ,user_data);
    const jsonData = JSON.stringify(user_data);
    console.log('json data ---', jsonData);
    localStorage.setItem('authenticated', jsonData);
    // localStorage.setItem('username', jsonData);
    // const user = localStorage.getItem('user') != "undefined" ? JSON.parse(localStorage.getItem('user')) : null;
    // console.log('set token', user);
  }

  private extractData(res: Response) {
    let body = res.json();
    return body || {};
  }
}
